﻿using System;
using System.Collections.Generic;
using System.Linq;
using CommonFramework.Serialize.BytesArray;
using NUnit.Framework;
using NUnit.Framework.Constraints;

namespace CommonFrameworkTest
{
    [TestFixture]
    public class TestBytesCompressUtil
    {
        private byte[] CreatePatternBytes(int length)
        {
            byte[] patterns = new byte[]
                {1, 13, 255, 0, 9, 23, 21, 4, 2, 1, 11, 4, 2, 2, 1, 5, 6, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8};
            Random rand = new Random();

            byte[] data = new byte[length];
            int filledLen = 0;
            while (filledLen < length)
            {
                int size = Math.Min(length - filledLen, (rand.Next() % patterns.Length) + 1);
                Buffer.BlockCopy(patterns,0,data,filledLen,size);
                filledLen += size;
            }
            return data;
        }

        [Test]
        public void TestCompressBytes_NullBytes_ReturnNull()
        {
            var result= BytesCompressUtil.CompressBytes(null);
            Assert.That(result,Is.Null);
        }

        [Test]
        public void TestCompressBytes_EmptyBytes_ReturnEmpty()
        {
            var result = BytesCompressUtil.CompressBytes(new byte[0]);
            Assert.That(result.Length,Is.EqualTo(0));
        }

        [Test]
        public void TestCompressBytes_RandomBytes_ReturnSmallerBytes()
        {
            byte[] input= CreatePatternBytes(20480);
            byte[] result= BytesCompressUtil.CompressBytes(input);

            Assert.That(result,Is.Not.Null);
            Assert.That(result.Length,Is.LessThan(input.Length));
        }

        [Test]
        public void TestCompressAndUncompressytes_RandomBytes_AreEqual()
        {
            byte[] input = CreatePatternBytes(2048);
            byte[] compressed = BytesCompressUtil.CompressBytes(input);
            byte[] result = BytesCompressUtil.UncompressBytes(compressed);

            Assert.That(result,Is.Not.Null);
            Assert.That(result.Length,Is.EqualTo(input.Length));
            Assert.That(result.SequenceEqual(input));
        }
    }
}